
package org.apache.mina.common;

import java.net.SocketAddress;
import java.util.Set;

/**
 * A handle which represents connection between two endpoints regardless of
 * transport types.
 * 
 * 一个代表两个终端之间的连接，不管其传输协议。
 * 
 * <p>
 * {@link IoSession} provides user-defined attributes. User-defined attributes
 * are application-specific data which is associated with a session. It often
 * contains objects that represents the state of a higher-level protocol and
 * becomes a way to exchange data between filters and handlers.
 * 
 * IoSession提供自定义的的属性，自定义属性是与session有联系的特定相关应用的数据。
 * 它经常包含一些代表高级协议状态的对象，并且成为一种用来在filter和handler之间交换数据的方式。
 * 
 * <h3>Adjusting Transport Type Specific Properties</h3>
 * 
 * 自适应的传输类型规范属性
 * 
 * <p>
 * You can simply downcast the session to an appropriate subclass.
 * </p>
 * 
 * 你可以简单地把session向下转型为适合的子类。
 * 
 * <h3>Thread Safety</h3>
 * <p>
 * {@link IoSession} is thread-safe. But please note that performing more than
 * one {@link #write(Object)} calls at the same time will cause the
 * {@link IoFilter#filterWrite(IoFilter.NextFilter, IoSession, IoFilter.WriteRequest)}
 * is executed simnutaneously, and therefore you have to make sure the
 * {@link IoFilter} implementations you're using are thread-safe, too.
 * </p>
 * 
 * 线程安全，IoSession是线程安全。但请注意，同时多次运行write(Object)方法，将导致
 * IoFilter.filterWrite(NextFilter,IoSession,WriteRequest)同时执行；
 * 因此你必须确保你所实现的IoFilter实现类。
 */
public interface IoSession {

    /**
     * Returns the {@link IoService} which provides I/O service to this session.
     * 
     * 返回为此会话提供IO服务的IoService。
     */
    IoService getService();

    /**
     * Returns the {@link IoServiceConfig} of this session.
     * 
     * 返回此会话的IoServiceConfig。
     */
    IoServiceConfig getServiceConfig();

    /**
     * Returns the {@link IoHandler} which handles this session.
     * 
     * 返回处理此会话的IoHandler。
     */
    IoHandler getHandler();

    /**
     * Returns the configuration of this session.
     * 
     * 返回此会话的配置。
     */
    IoSessionConfig getConfig();

    /**
     * Returns the filter chain that only affects this session.
     * 
     * 返回只影响这个该会话的过滤链。
     */
    IoFilterChain getFilterChain();

    /**
     * Writes the specified <code>message</code> to remote peer. This operation
     * is asynchronous; {@link IoHandler#messageSent(IoSession, Object)} will be
     * invoked when the message is actually sent to remote peer. You can also
     * wait for the returned {@link WriteFuture} if you want to wait for the
     * message actually written.
     * 
     * 发送指定的message到远程设备。该操作是异步的；当信息真正地发送到远程设备时，将会调用
     * IoHandler.messageSent(IoSession,Object)方法。你也可以等待它返回WriteFuture。
     */
    WriteFuture write(Object message);

    /**
     * Closes this session immediately. This operation is asynthronous. Wait for
     * the returned {@link CloseFuture} if you want to wait for the session
     * actually closed.
     * 
     * 立即关闭此会话。
     */
    CloseFuture close();

    /**
     * Returns an attachment of this session. This method is identical with
     * <tt>getAttribute( "" )</tt>.
     */
    Object getAttachment();

    /**
     * Sets an attachment of this session. This method is identical with
     * <tt>setAttribute( "", attachment )</tt>.
     * 
     * @return Old attachment. <tt>null</tt> if it is new.
     */
    Object setAttachment(Object attachment);

    /**
     * Returns the value of user-defined attribute of this session.
     * 
     * 根据key返回此会话的自定义的属性。
     * 
     * @param key
     *            the key of the attribute
     * @return <tt>null</tt> if there is no attribute with the specified key
     */
    Object getAttribute(String key);

    /**
     * Sets a user-defined attribute.
     * 
     * 设置自定义属性。
     * 
     * @param key
     *            the key of the attribute
     * @param value
     *            the value of the attribute
     * @return The old value of the attribute. <tt>null</tt> if it is new.
     */
    Object setAttribute(String key, Object value);

    /**
     * Sets a user defined attribute without a value. This is useful when you
     * just want to put a 'mark' attribute. Its value is set to
     * {@link Boolean#TRUE}.
     * 
     * 设置没有值的自定义属性。当你仅仅需要添加一个标识的属性时，该方法则会派上用场。它的默认值是BOOLEAN.TRUE。
     * 
     * @param key
     *            the key of the attribute
     * @return The old value of the attribute. <tt>null</tt> if it is new.
     */
    Object setAttribute(String key);

    /**
     * Removes a user-defined attribute with the specified key.
     * 
     * 根据指定的key移除一个自定义属性。
     * 
     * @return The old value of the attribute. <tt>null</tt> if not found.
     */
    Object removeAttribute(String key);

    /**
     * Returns <tt>true</tt> if this session contains the attribute with the
     * specified <tt>key</tt>.
     * 
     * 此会话是否包含指定的key的属性。
     */
    boolean containsAttribute(String key);

    /**
     * Returns the set of keys of all user-defined attributes.
     * 
     * 返回所有自定义属性的集合。
     */
    Set<String> getAttributeKeys();

    /**
     * Returns transport type of this session.
     * 
     * 返回传输类型。
     */
    TransportType getTransportType();

    /**
     * Returns <code>true</code> if this session is connected with remote peer.
     * 
     * 当前会话是否连接到远程设备。
     */
    boolean isConnected();

    /**
     * Returns <code>true</tt> if and only if this session is being closed
     * (but not disconnected yet) or is closed.
     * 
     * 判断当前会话是否即将关闭（未断开连接）或已经关闭。
     */
    boolean isClosing();

    /**
     * Returns the {@link CloseFuture} of this session. This method returns the
     * same instance whenever user calls it.
     * 
     * 返回此会话的CloseFuture。不管什么时候调用，该方法返回的都是同一对象。
     */
    CloseFuture getCloseFuture();

    /**
     * Returns the socket address of remote peer.
     * 
     * 返回远程设备的地址。
     */
    SocketAddress getRemoteAddress();

    /**
     * Returns the socket address of local machine which is associated with this
     * session.
     * 
     * 返回与此会话关联的本地地址
     */
    SocketAddress getLocalAddress();

    /**
     * Returns the socket address of the {@link IoService} listens to to manage
     * this session. If this session is managed by {@link IoAcceptor}, it
     * returns the {@link SocketAddress} which is specified as a parameter of
     * {@link IoAcceptor#bind(SocketAddress, IoHandler)}. If this session is
     * managed by {@link IoConnector}, this method returns the same address with
     * that of {@link #getRemoteAddress()}.
     * 
     * 返回监听、管理此会话的IoService的socket地址。如果此会话由IoAcceptor管理，它返回的由
     * IoAcceptor.bind(SocketAddress,IoHandler)方法设置的SocketAddress。
     * 如果此会话由IoConnector管理，它返回的地址与getRemoteAddress()是相同的。
     */
    SocketAddress getServiceAddress();

    /**
     * Returns idle time for the specified type of idleness in seconds.
     * 
     * 返回指定空闲状态的连接超时，单位为秒。
     */
    int getIdleTime(IdleStatus status);

    /**
     * Returns idle time for the specified type of idleness in milliseconds.
     * 返回指定空闲状态的连接超时，单位为毫秒。
     */
    long getIdleTimeInMillis(IdleStatus status);

    /**
     * Sets idle time for the specified type of idleness in seconds.
     */
    void setIdleTime(IdleStatus status, int idleTime);

    /**
     * Returns write timeout in seconds.
     * 
     * 返回写数据的连接超时，单位为秒。
     */
    int getWriteTimeout();

    /**
     * Returns write timeout in milliseconds.
     * 
     * 返回写数据的连接超时，单位为毫秒。
     */
    long getWriteTimeoutInMillis();

    /**
     * Sets write timeout in seconds.
     */
    void setWriteTimeout(int writeTimeout);

    /**
     * Returns the current {@link TrafficMask} of this session.
     * 
     * 返回此会话当前的TrafficMask。
     */
    TrafficMask getTrafficMask();

    /**
     * Sets the {@link TrafficMask} of this session which will result the parent
     * {@link IoService} to start to control the traffic of this session
     * immediately.
     */
    void setTrafficMask(TrafficMask trafficMask);

    /**
     * A shortcut method for {@link #setTrafficMask(TrafficMask)} that suspends
     * read operations for this session.
     */
    void suspendRead();

    /**
     * A shortcut method for {@link #setTrafficMask(TrafficMask)} that suspends
     * write operations for this session.
     */
    void suspendWrite();

    /**
     * A shortcut method for {@link #setTrafficMask(TrafficMask)} that resumes
     * read operations for this session.
     */
    void resumeRead();

    /**
     * A shortcut method for {@link #setTrafficMask(TrafficMask)} that resumes
     * write operations for this session.
     */
    void resumeWrite();

    /**
     * Returns the total number of bytes which were read from this session.
     */
    long getReadBytes();

    /**
     * Returns the total number of bytes which were written to this session.
     */
    long getWrittenBytes();

    /**
     * Returns the total number of messages which were read and decoded from
     * this session.
     */
    long getReadMessages();

    /**
     * Returns the total number of messages which were written and encoded by
     * this session.
     */
    long getWrittenMessages();

    /**
     * Returns the total number of write requests which were written to this
     * session.
     */
    long getWrittenWriteRequests();

    /**
     * Returns the number of write requests which are scheduled to be written to
     * this session.
     */
    int getScheduledWriteRequests();

    /**
     * Returns the number of bytes which are scheduled to be written to this
     * session.
     */
    int getScheduledWriteBytes();

    /**
     * Returns the time in millis when this session is created.
     */
    long getCreationTime();

    /**
     * Returns the time in millis when I/O occurred lastly.
     */
    long getLastIoTime();

    /**
     * Returns the time in millis when read operation occurred lastly.
     */
    long getLastReadTime();

    /**
     * Returns the time in millis when write operation occurred lastly.
     */
    long getLastWriteTime();

    /**
     * Returns <code>true</code> if this session is idle for the specified
     * {@link IdleStatus}.
     */
    boolean isIdle(IdleStatus status);

    /**
     * Returns the number of the fired continuous <tt>sessionIdle</tt> events
     * for the specified {@link IdleStatus}.
     * <p>
     * If <tt>sessionIdle</tt> event is fired first after some time after I/O,
     * <tt>idleCount</tt> becomes <tt>1</tt>. <tt>idleCount</tt> resets to
     * <tt>0</tt> if any I/O occurs again, otherwise it increases to <tt>2</tt>
     * and so on if <tt>sessionIdle</tt> event is fired again without any I/O
     * between two (or more) <tt>sessionIdle</tt> events.
     */
    int getIdleCount(IdleStatus status);

    /**
     * Returns the time in millis when the last <tt>sessionIdle</tt> event is
     * fired for the specified {@link IdleStatus}.
     */
    long getLastIdleTime(IdleStatus status);
}
